package controllers

import (
	"net/http"
	"os"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"

	"dcarpai-guider/internal/utils"
)

// HealthController 健康检查控制器
type HealthController struct {
	logger       *zap.Logger
	consulClient *utils.ConsulClient
	startTime    time.Time
}

// NewHealthController 创建新的健康检查控制器
func NewHealthController(logger *zap.Logger, consulClient *utils.ConsulClient) *HealthController {
	return &HealthController{
		logger:       logger,
		consulClient: consulClient,
		startTime:    time.Now(),
	}
}

// BasicHealth 基础健康检查
// @Summary 基础健康检查
// @Description 返回服务基本健康状态
// @Tags 健康检查
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /health [get]
func (hc *HealthController) BasicHealth(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status":    "ok",
		"timestamp": time.Now().Unix(),
		"service":   "dcarpai-guider",
		"uptime":    time.Since(hc.startTime).String(),
		"version":   "1.0.0",
	})
}

// DetailedHealth 详细健康检查
// @Summary 详细健康检查
// @Description 返回详细的系统健康状态，包括各组件状态
// @Tags 健康检查
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /api/v1/health/detailed [get]
func (hc *HealthController) DetailedHealth(c *gin.Context) {
	health := gin.H{
		"status":    "ok",
		"timestamp": time.Now().Unix(),
		"service":   "dcarpai-guider",
		"uptime":    time.Since(hc.startTime).String(),
		"version":   "1.0.0",
		"components": gin.H{
			"database": hc.checkFileSystem(),
			"logging":  hc.checkLogging(),
		},
	}

	// 检查Consul连接
	if hc.consulClient != nil {
		health["components"].(gin.H)["consul"] = hc.checkConsul()
	}

	// 计算整体健康状态
	allHealthy := true
	for _, component := range health["components"].(gin.H) {
		if comp, ok := component.(gin.H); ok {
			if status, exists := comp["status"]; exists && status != "healthy" {
				allHealthy = false
				break
			}
		}
	}

	if !allHealthy {
		health["status"] = "degraded"
		c.JSON(http.StatusServiceUnavailable, health)
		return
	}

	c.JSON(http.StatusOK, health)
}

// checkFileSystem 检查文件系统健康状态
func (hc *HealthController) checkFileSystem() gin.H {
	// 检查数据目录是否可访问
	if _, err := os.Stat("./data"); err != nil {
		return gin.H{
			"status":  "unhealthy",
			"message": "Data directory not accessible",
			"error":   err.Error(),
		}
	}

	// 检查日志目录是否可访问
	if _, err := os.Stat("./logs"); err != nil {
		return gin.H{
			"status":  "unhealthy",
			"message": "Log directory not accessible",
			"error":   err.Error(),
		}
	}

	return gin.H{
		"status":  "healthy",
		"message": "File system is accessible",
	}
}

// checkLogging 检查日志系统健康状态
func (hc *HealthController) checkLogging() gin.H {
	// 简单的日志健康检查
	hc.logger.Info("Health check: logging system test")

	return gin.H{
		"status":  "healthy",
		"message": "Logging system is operational",
	}
}

// checkConsul 检查Consul连接健康状态
func (hc *HealthController) checkConsul() gin.H {
	if hc.consulClient == nil {
		return gin.H{
			"status":  "disabled",
			"message": "Consul client not configured",
		}
	}

	// 尝试获取服务健康状态
	if _, err := hc.consulClient.GetServiceHealths(); err != nil {
		return gin.H{
			"status":  "unhealthy",
			"message": "Consul connection failed",
			"error":   err.Error(),
		}
	}

	return gin.H{
		"status":  "healthy",
		"message": "Consul connection is active",
	}
}

// GetReadiness 就绪检查
// @Summary 服务就绪检查
// @Description 检查服务是否准备好接收流量
// @Tags 健康检查
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Failure 503 {object} map[string]interface{}
// @Router /health/ready [get]
func (hc *HealthController) GetReadiness(c *gin.Context) {
	// 检查关键组件是否就绪
	ready := true
	components := gin.H{}

	// 检查文件系统
	if fsHealth := hc.checkFileSystem(); fsHealth["status"] != "healthy" {
		ready = false
		components["filesystem"] = fsHealth
	}

	// 检查是否已运行足够时间(避免启动时的瞬时检查)
	if time.Since(hc.startTime) < 5*time.Second {
		ready = false
		components["startup"] = gin.H{
			"status":  "starting",
			"message": "Service is still starting up",
		}
	}

	status := gin.H{
		"ready":     ready,
		"timestamp": time.Now().Unix(),
		"uptime":    time.Since(hc.startTime).String(),
	}

	if len(components) > 0 {
		status["components"] = components
	}

	if ready {
		c.JSON(http.StatusOK, status)
	} else {
		c.JSON(http.StatusServiceUnavailable, status)
	}
}

// GetLiveness 存活检查
// @Summary 服务存活检查
// @Description 检查服务是否仍在运行
// @Tags 健康检查
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /health/live [get]
func (hc *HealthController) GetLiveness(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"alive":     true,
		"timestamp": time.Now().Unix(),
		"uptime":    time.Since(hc.startTime).String(),
		"pid":       os.Getpid(),
	})
}
